﻿

using F29ServerProcess.Interfaces;
using F29ServerProcess.Models;
using IotContract.Dtos.Servers.Process;
using IotContract.Dtos.Servers.Pushs;
using IotContract.Enums;
using IotContract.Interfaces;
using IotContract.Interfaces.Process;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;
using XT.Common.Extensions;
using XT.Common.Services;

namespace _29ServerProcess.DataProcess;
/// <summary>
/// 插钉机数据处理程序
/// </summary>
public class PinOutDataProcess : IServerProcessHandle
{

    private readonly IServerMainManager _mainProcess;
    private readonly IProcessDataService _processDataService;
    private readonly ILogService _logService;

    public PinOutDataProcess(IServerMainManager serverMainManager, IProcessDataService processDataService, ILogService logService)
    {
        _mainProcess = serverMainManager;
        _processDataService = processDataService;
        _logService = logService;
    }
    public string ProcessName { get; set; } =  F29ServerConst.ProcessName;
    public IotEquipType ProcessType { get; set; } = IotEquipType.PINOUT;




    public async Task<bool> ParsingData()
    {
        try
        {
            // 获取数据
            var equips = await _mainProcess.GetEquips<PushSiemensS7Dto>(new IotContract.Models.Clients.ClientRequestCommand
            {
                RequestType = IotEquipType.PINOUT.ToString(),
                ProtobufType = IotProtobufType.SIEMENS_S7.ToString()
            });


            var pinOutUnitDic = _processDataService.PinOutUnits;
            // 拘束机点位不需要设置UnitNum
            Parallel.ForEach(equips, equip =>
            {
                var tags = equip.Tags;
                F29PinOutUnitDto pinOutUnit = null;
                if (pinOutUnitDic.ContainsKey(equip.Num))
                {
                    pinOutUnit = pinOutUnitDic[equip.Num];
                }
                else
                {
                    pinOutUnit = new F29PinOutUnitDto();
                    pinOutUnit.EquipNum = equip.Num;
                    pinOutUnit.EquipId = equip.Id;
                    pinOutUnit.Connection = equip.Connection;
                    pinOutUnitDic.TryAdd(equip.Num, pinOutUnit);
                }
                SetUnitTag(pinOutUnit, tags);
            });
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }

        return true;
    }

    /// <summary>
    /// 取值
    /// </summary>
    /// <param name="scUnit"></param>
    /// <param name="tags"></param>
    private void SetUnitTag(F29PinOutUnitDto pinOutUnit, List<PushEquipTag> tags)
    {
        pinOutUnit.Tags = tags;
        Parallel.ForEach(pinOutUnit.Tags, tag =>
        {
            int.TryParse(tag.Value, out int result);
            switch (tag.TagProperty)
            {
                case "ERROR":
                    {
                        pinOutUnit.Error = result;
                        break;
                    }
                case "MODE":
                    {
                        pinOutUnit.Mode = result;
                        break;
                    }
                case "WORK_DONE":
                    {
                        pinOutUnit.WorkDone = result;
                        break;
                    }
                case "WORK_START":
                    {
                        pinOutUnit.WorkStart = result;
                        break;
                    }
                case "TRAY":
                    {
                        pinOutUnit.Tray = tag.Value;
                        break;
                    }
                case "TRAY_ARRIVE":
                    {
                        pinOutUnit.TrayArrive = result;
                        break;
                    }
            }
        });
    }

    public async Task<bool> ProcessData()
    {
        foreach(var pinOut in _processDataService.PinOutUnits.Values)
        {
            if (pinOut.Tray.IsNullOrEmpty() || pinOut.Tray.Replace("\0", "").IsNullOrEmpty() || pinOut.Mode==0)
            {
                pinOut.Status = 0;
                pinOut.Message = string.Empty;
                continue;
            }
            if (pinOut.Message.IsNotNullOrEmpty()) continue;
            // 托盘到达  要写入动作信息W_ACTION 1：作业     2：通过
            // 当作业开始前，写入W_WORK_START,确认开始作业
            // 作业结束后，写入W_WORK_DONE，确认作业完成
            if (pinOut.TrayArrive == 1 && pinOut.Status == 0 && pinOut.WorkStart == 0)
            {
                // 验证数据
                var result = await _processDataService.ValidateEnterTray(pinOut.EquipNum, ProcessType, pinOut.Tray);

                if (result.Success)
                {
                    await _processDataService.WritePinOut("W_BCR_DONE", pinOut.EquipNum);
                    await _processDataService.WritePinOut("W_ACTION", pinOut.EquipNum);

                    pinOut.Status = 1;

                }
                else
                {
                    // 有NG信息
                    pinOut.Message = result.Message;
                    await Task.Delay(500);
                }
            }
            else if (pinOut.Status == 1 && pinOut.WorkDone == 1)
            {
                var oResult = await _processDataService.ValidateOutTray(pinOut.EquipNum, ProcessType, pinOut.Tray);
                if (oResult.Success)
                {

                    await _processDataService.WritePinOut("W_WORK_DONE", pinOut.EquipNum);

                    pinOut.Status = 2;
                }
                else
                {
                    pinOut.Message = oResult.Message;
                    await Task.Delay(500);
                }
            }

           
        }
        return true;
    }

    public async Task<bool> ProcessOrder()
    {
        return true;
    }

    public async Task<bool> ProcessWarn()
    {
        return true;
    }

    public bool Stop()
    {
        _processDataService.ScUnits.Clear();
        return true;
    }
}
